﻿using BCCommon;
using BCCommon.FreightEnums;
using BCData.Common.Area;
using BCDto.Common.Area;
using BCDto.Sim.Admin.Admin;
using BCEntity;
using BCEntity.Common.Area;
using BCEntity.Common.EntityNameConst;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BCService.Common.Area
{
    public class ProvinceService : IProvinceService
    {
        protected readonly IProvinceData provinceData;
        protected readonly ICityData cityData;
        protected readonly ICountyData countyData;
        protected readonly IRedisService redisService;
        protected readonly string key = string.Format("{0}", EntityNameConst.ProvinceEntity);

        public ProvinceService(IProvinceData provinceData, ICityData cityData, IRedisService redisService, ICountyData countyData)
        {
            this.provinceData = provinceData;
            this.cityData = cityData;
            this.redisService = redisService;
            this.countyData = countyData;
        }

        public bool Add(ProvinceRequestDto dto,AdminDto adminDto)
        {
            if (provinceData.CheckProvinceExistsByCode(dto.ProvinceCode))
            {
                throw new ArgumentException("省份编码已存在");
            }
            ProvinceEntity entity = dto.As<ProvinceEntity>();
            entity.IsEnabled = true;
            entity.Editer = adminDto.FullName;
            return provinceData.Add(entity);
        }

        public void Delete(string provinceCode)
        {
            if (!provinceData.CheckProvinceExistsByCode(provinceCode))
            {
                throw new ArgumentException("省份编码不存在");
            }
            if (provinceData.CheckProvinceIdInUsed(provinceCode))
            {
                throw new ArgumentException("此省份编码已在使用中，无法删除");
            }
            bool result = provinceData.Delete(provinceCode);
            if (result)
            {
                string cacheKey = this.redisService.GetKey(key, provinceCode);
                redisService.Delete(cacheKey);
            }
        }
        public ProvinceDto GetProvinceEntity(long provinceId)
        {
            string cacheKey = this.redisService.GetKey(key, provinceId);
            var entity = this.redisService.TryGet(cacheKey, () => provinceData.GetProvince(provinceId));

            return entity.As<ProvinceDto>();
        }
        public ProvinceDto GetProvinceEntity(string provinceCode)
        {
            string cacheKey = this.redisService.GetKey(key, provinceCode);
            var entity = this.redisService.TryGet(cacheKey, () => provinceData.GetProvince(provinceCode));

            return entity.As<ProvinceDto>();
        }

        public PageableList<ProvinceDto> GetProvinces(string provinceCode,int index, int size)
        {
            string cacheKey = this.redisService.GetKey(key, provinceCode, index,size);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var list = provinceData.GetProvinces(provinceCode, index, size, out int dataCount);
                PageableList<ProvinceDto> pageList = new PageableList<ProvinceDto>
                {
                    Count = dataCount,
                    Items = list.As<IEnumerable<ProvinceDto>>()
                };
                return pageList;
            });
            return result;
        }

        public void Update(ProvincePutDto dto,AdminDto adminDto)
        {
            if (!this.provinceData.CheckProvinceExistsById(dto.ProvinceId))
            {
                throw new ArgumentException("此省份信息不存在");
            }
            var oldEntity = this.provinceData.GetProvince(dto.ProvinceId);
            if (oldEntity.ProvinceCode != dto.ProvinceCode)
            {
                if (this.provinceData.CheckProvinceExistsByCode(dto.ProvinceCode))
                {
                    throw new ArgumentException("此省份编码已存在");
                }
            }

            var entity = dto.As<ProvinceEntity>();
            entity.Editer = adminDto.FullName;
            entity.UpdateTime = DateTime.Now;
            var result = provinceData.Update(entity);
            if (result)
            {
                string cacheKey = string.Format("{0}:ProvinceId={1}", key, dto.ProvinceId);
                redisService.DeleteMultipleKey(cacheKey,false);
            }
        }

        public void UpdateProvinceNegotiatedPrice(string provinceCode, FreightBusinessType businessType, bool isNegotiatedPrice)
        {
            if (!this.provinceData.CheckProvinceExistsByCode(provinceCode))
            {
                throw new ArgumentException(string.Format("不存在省份编码:{0}", provinceCode));
            }
            int status = 0;
            while (status == 0)
            {
                status = this.provinceData.UpdateProvinceNegotiatedPrice(provinceCode, businessType, isNegotiatedPrice).GetAwaiter().GetResult();
            }
            this.cityData.UpdateAllCityNegotiatedPrice(provinceCode, businessType, isNegotiatedPrice);
        }

        public IEnumerable<ProvinceCityDto> GetAllProvinces()
        {
            string key = string.Format("{0}", EntityNameConst.ProvinceCityEntity);
            var result = this.redisService.TryGet(key, () => {
                var list = provinceData.GetProvinces().As<IEnumerable<ProvinceCityEntity>>(); 
                var cityList = cityData.GetAllCity();
                foreach (var item in list)
                {
                    item.CityList = cityList.Where(g => g.ProvinceCode == item.ProvinceCode).ToList();
                }
                return list.As<IEnumerable<ProvinceCityDto>>();
            }, TimeSpan.FromMinutes(30));
            return result;
        }

        public void UpdateCoordinate(string tableName, string provinceCode, double longitude, double latitude)
        {
            //string colName = null;
            //string key = null;
            //if (tableName == "Province")
            //{
            //    key = string.Format("{0}:ProvinceCode={1}", EntityNameConst.ProvinceEntity, provinceCode);
            //    if (!provinceData.CheckProvinceExistsById(provinceCode))
            //    {
            //        throw new ArgumentException("省份编码不存在");
            //    }
            //}
            //else if (tableName == "City")
            //{
            //    key = string.Format("{0}:CityCode={1}", EntityNameConst.CityEntity, provinceCode);
            //    if (!cityData.CheckExistsById(provinceCode))
            //    {
            //        throw new ArgumentException("城市编码不存在");
            //    }
            //}
            //else if (tableName == "County")
            //{
            //    key = string.Format("{0}:CountyCode={1}", EntityNameConst.CountyEntity, provinceCode);
            //    if (!countyData.CheckExistsById(provinceCode))
            //    {
            //        throw new ArgumentException("区县编码不存在");
            //    }
            //}
            var result = provinceData.UpdateCoordinate(tableName, provinceCode, longitude, latitude);
        }

        public ProvinceDto UpdateProvince(string editer, string provinceCode, string provinceName, double longitude, double latitude, string batchNo)
        {
            ProvinceEntity entity = new ProvinceEntity()
            {
                ProvinceCode = provinceCode,
                ProvinceName = provinceName,
                ProvinceHeatLevel = 0,
                ProvinceEasyBackGoods = EasyBackGoodsType.Normal,
                Editer = editer,
                ProvinceNegotiatedPrice = false,
                ProvinceNegotiatedPricePartLoad = false,
                Longitude = longitude,
                Latitude = latitude,
                IsEnabled = true
            };
            int status = 0;
            var provinceResult = this.provinceData.GetProvinceAsync(null, null, entity.ProvinceCode).GetAwaiter().GetResult();
            if (provinceResult == null)
            {
                while (status == 0)
                {
                    status = provinceData.AddProvinceAsync(entity, batchNo).GetAwaiter().GetResult();
                }
            }
            else
            {
                entity.ProvinceUuid = provinceResult.ProvinceUuid;
                if (provinceResult.ProvinceName == provinceName && provinceResult.ProvinceCode == provinceCode)
                {
                    while (status == 0)
                    {
                        status = provinceData.UpdateProvinceAsync(entity, null, null, null).GetAwaiter().GetResult();
                    }
                }
                else
                {
                    while (status == 0)
                    {
                        status = provinceData.UpdateProvinceAsync(entity, batchNo, provinceResult, false).GetAwaiter().GetResult();
                    }
                }
            }
            var result = this.provinceData.GetProvinceAsync(null, null, provinceCode).GetAwaiter().GetResult();
            return result.As<ProvinceDto>();
        }

        public bool UpdateIsEnabled(string batchNo)
        {
            if (!provinceData.UpdateIsEnabledAsync(batchNo).GetAwaiter().GetResult())
            {
                return false;
            }
            return true;
        }
    }
}
